// ----------------------------------------
// Filename: Flash.h
// Description: Routines to R/W flash memory
// Author: Anton Jatmiko
// Date: 31 May 2014

#ifndef FLASH_H
#define	FLASH_H

#include <xc.h>
#include "types.h"
#include "SPI.h"

#define _XTAL_FREQ                 4000000
#define FLASH_WPROTECTN            LATDbits.LD4
#define FLASH_HOLDN                LATDbits.LD5
#define FLASH_CSN                  LATDbits.LD3

static const UINT8 WriteEnableCMD = 0x06;
static const UINT8 WriteDisableCMD = 0x04;
static const UINT8 ReadStatCMD = 0x05;
static const UINT8 WriteStatCMD = 0x01;
static const UINT8 ReadDataNormSCMD = 0x03;
static const UINT8 ReadDataHighSCMD = 0x0B;
static const UINT8 PageProgCMD = 0x02;
static const UINT8 EraseSectorCMD = 0xD8;
static const UINT8 EraseBulkCMD = 0xC7;
static const UINT8 StatData = 0x00;             // Disable Block Protect and SRWD
static const UINT32 StrtAddrSect0 = 0;
static const UINT32 StrtAddrSect1 = 0x00010000;
static const UINT32 StrtAddrSect2 = 0x00020000;
static const UINT32 StrtAddrSect3 = 0x00030000;

UINT8 Flash_RxData = 0;
extern TUINT16 CelcX10;

// ----------------------------------------
// Flash_Init
//
// Initialise flash
// Input:
//   none
// Output:
//   none
// Conditions:
//   none
void Flash_Init(void);

// ----------------------------------------
// Flash_Select
//
// Initialise HMI (buttons and LEDs)
// Input:
//   chipSelect is a boolean indicates whether or not to select the flash
// Output:
//   none
// Conditions:
//   assume flash is idle
void Flash_Select(BOOL chipSelect);

// ----------------------------------------
// Flash_WriteAddressCount
//
// Count the number of byte in the flash that contains information
// Input:
//   none
// Output:
//   none
// Conditions:
//   none
void Flash_WriteAddressCount(void);

// ----------------------------------------
// Flash_WriteEnable
//
// Enable flash write
// Input:
//   none
// Output:
//   none
// Conditions:
//   assume write enable command has been sent
void Flash_WriteEnable(void);

// ----------------------------------------
// Flash_WriteCMD
//
// Initiate the slave select and send command
// Input:
//   cmd is the command to be sent
// Output:
//   none
// Conditions:
//   assume the flash is idle
void Flash_WriteCMD(UINT8 cmd);

// ----------------------------------------
// Flash_ReadStat
//
// Read the status byte of the flash
// Input:
//   dataPtr is a pointer to the status variable
// Output:
//   none
// Conditions:
//   assume read status command has been sent
void Flash_ReadStat(UINT8 * const dataPtr);

// ----------------------------------------
// Flash_ResetCBR
//
// Reset the counters associated with flash read
// Input:
//   none
// Output:
//   none
// Conditions:
//   none
void Flash_ResetCBR(void);

// ----------------------------------------
// Flash_ReadByte
//
// Read the flash from address zero
// Input:
//   none
// Output:
//   TRUE if a useful byte is retireved
// Conditions:
//   assume read command has been sent
BOOL Flash_ReadByte(UINT8 * const dataPtr);

// ----------------------------------------
// Flash_BulkErase
//
// Erase the entire memory in the flash
// Input:
//   none
// Output:
//   none
// Conditions:
//   none
void Flash_BulkErase(void);

// ----------------------------------------
// Flash_Write2Byte
//
// Write 2 bytes to the flash
// Input:
//   data is the 2 bytes data to be written
// Output:
//   none
// Conditions:
//   assume page program command has been sent
void Flash_Write2Byte(TUINT16 data);

// ----------------------------------------
// Flash_CMDHandle
//
// Handle flash command
// Input:
//   cmd is the flash command
// Output:
//   TRUE if a useful byte is retireved
// Conditions:
//   assume flash command has been written
BOOL Flash_CMDHandle(const UINT8 cmd);

#endif